package com.tanker.base.plugin;

import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.*;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.Document;
import org.mybatis.generator.api.dom.xml.TextElement;
import org.mybatis.generator.api.dom.xml.XmlElement;

import java.util.List;

/**
 * Created by marcos on 16/1/13.
 */
public class SelectOneByExamplePlugin extends PluginAdapter {



    @Override
    public boolean validate(List<String> warnings) {
        return true;
    }




    /**
     * select
     * <if test="distinct" >
     * distinct
     * </if>
     * <include refid="Base_Column_List" />
     * from STUDENT
     * <if test="_parameter != null" >
     * <include refid="Example_Where_Clause" />
     * </if>
     * <if test="orderByClause != null" >
     * order by ${orderByClause}
     * </if>
     *
     * @param document
     * @param introspectedTable
     * @return
     */
    @Override
    public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {
        String tableName = introspectedTable.getTableConfiguration().getTableName();
        String sharding=introspectedTable.getTableConfiguration().getProperty("Sharding");
        XmlElement selectOneByExample = new XmlElement("select");
        selectOneByExample.addAttribute(new Attribute("id", "selectOneByExample"));
        selectOneByExample.addAttribute(new Attribute("resultMap", "BaseResultMap"));
        selectOneByExample.addAttribute(new Attribute("parameterType", introspectedTable.getExampleType()));
        selectOneByExample.addElement(new TextElement("select"));
        XmlElement distictElement = new XmlElement("if");
        distictElement.addAttribute(new Attribute("test", "distinct"));
        distictElement.addElement(new TextElement("distinct"));
        selectOneByExample.addElement(distictElement);

        /*XmlElement baseColumnElement = new XmlElement("include");
        baseColumnElement.addAttribute(new Attribute("refid", "Base_Column_List"));
        selectOneByExample.addElement(baseColumnElement);*/
        selectOneByExample.addElement(new TextElement("<if test=\"includeColumns == null or includeColumns.size()==0\" >\n" +
                "      <include refid=\"Base_Column_List\" />\n" +
                "    </if>\n" +
                "    <if test=\"includeColumns!=null and includeColumns.size() > 0\" >\n" +
                "      <foreach collection=\"includeColumns\" index=\"index\" item=\"includeColumn\" separator=\",\" >\n" +
                "        ${includeColumn}\n" +
                "      </foreach>\n" +
                "    </if>"));

        selectOneByExample.addElement(new TextElement(" from " + tableName));

        selectOneByExample.addElement(new TextElement("<if test=\"_parameter != null\" >\n" +
                "     <include refid=\"Example_Where_Clause\" />\n" +
                "     </if>"));

        selectOneByExample.addElement(new TextElement("<if test=\"orderByClause != null\" >\n" +
                "     order by ${orderByClause}\n" +
                "     </if>"));
        selectOneByExample.addElement(new TextElement("LIMIT 1 OFFSET 0"));
        if(sharding!=null&&sharding.equals("true")){
            addElementBySharding(document,introspectedTable);
        }
        document.getRootElement().addElement(selectOneByExample);
        return super.sqlMapDocumentGenerated(document, introspectedTable);
    }

    public void addElementBySharding(Document document, IntrospectedTable introspectedTable){
        String tableName = introspectedTable.getTableConfiguration().getTableName();
        XmlElement selectOneByExample = new XmlElement("select");
        selectOneByExample.addAttribute(new Attribute("id", "selectOneByExampleForSharding"));
        selectOneByExample.addAttribute(new Attribute("resultMap", "BaseResultMap"));
        selectOneByExample.addAttribute(new Attribute("parameterType", introspectedTable.getExampleType()));
        selectOneByExample.addElement(new TextElement("select"));
        XmlElement distictElement = new XmlElement("if");
        distictElement.addAttribute(new Attribute("test", "distinct"));
        distictElement.addElement(new TextElement("distinct"));
        selectOneByExample.addElement(distictElement);

        selectOneByExample.addElement(new TextElement("<if test=\"includeColumns == null or includeColumns.size()==0\" >\n" +
                "      <include refid=\"Base_Column_List\" />\n" +
                "    </if>\n" +
                "    <if test=\"includeColumns!=null and includeColumns.size() > 0\" >\n" +
                "      <foreach collection=\"includeColumns\" index=\"index\" item=\"includeColumn\" separator=\",\" >\n" +
                "        ${includeColumn}\n" +
                "      </foreach>\n" +
                "    </if>"));

        selectOneByExample.addElement(new TextElement(" from " + tableName));

        selectOneByExample.addElement(new TextElement("<if test=\"_parameter != null\" >\n" +
                "     <include refid=\"Example_Where_Clause\" />\n" +
                "     </if>"));

        selectOneByExample.addElement(new TextElement("<if test=\"orderByClause != null\" >\n" +
                "     order by ${orderByClause}\n" +
                "     </if>"));
        document.getRootElement().addElement(selectOneByExample);
    }

    /**
     * 随便找个方法加入mapper方法
     * @param method
     * @param interfaze
     * @param introspectedTable
     * @return
     */
    @Override
    public boolean clientCountByExampleMethodGenerated(Method method, Interface interfaze, IntrospectedTable introspectedTable) {
        Method selectOneByExampleMethod = new Method("selectOneByExample");
        String exampleType = introspectedTable.getExampleType();
        selectOneByExampleMethod.addParameter(new Parameter(new FullyQualifiedJavaType(exampleType),"example"));
        selectOneByExampleMethod.setReturnType(new FullyQualifiedJavaType(introspectedTable.getBaseRecordType()));
        interfaze.getMethods().add(selectOneByExampleMethod);

        return super.clientCountByExampleMethodGenerated(method, interfaze, introspectedTable);
    }

    @Override
    public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        String sharding=introspectedTable.getTableConfiguration().getProperty("Sharding");
        if(sharding!=null&&sharding.equals("true")){
            interfaze.addImportedType(new FullyQualifiedJavaType("java.util.List"));
            String getMapperpackagePath = introspectedTable.getContext().getJavaClientGeneratorConfiguration().getTargetPackage();
            String modelName = introspectedTable.getFullyQualifiedTable().getDomainObjectName();
            String exampleName = modelName+"Example";
            Method method = new Method();
            method.setVisibility(JavaVisibility.PUBLIC);
            method.setReturnType(new FullyQualifiedJavaType("List<"+modelName+">"));
            method.setName("selectOneByExampleForSharding");
            method.addParameter(new Parameter(new FullyQualifiedJavaType(getMapperpackagePath + "." + exampleName), exampleName.toLowerCase()));
            interfaze.addMethod(method);
        }
        return true;
    }

}
